package com.fognl.core.net.handler;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/** Manages tasks related to requests. */
public class WorkerManager implements WorkerTask.Listener
{
	private Map<RequestHandle, WorkerTask> pendingRequests = new HashMap<RequestHandle, WorkerTask>();
	private ExecutorService executor = Executors.newFixedThreadPool(10);
	
	public WorkerManager()
	{
		super();
	}
	
	/** Called when a WorkerTask is done with its work, whether successful or not. */
	public synchronized void onTaskComplete(WorkerTask task)
	{
		try {
			ResponseListener listener = task.requestHandle.responseListener;
			Request request = task.requestHandle.getRequest();
			
			if(task.workerException != null)
				listener.onRequestException(request, task.workerException);
			else if(task.timeoutError)
				listener.onRequestTimeout(request);
			else if(task.cancelled)
				listener.onRequestCancel(request);
			else
				listener.onRequestComplete(request, new Response(task.workerData));
		}
		finally {
			getPendingRequests().remove(task.requestHandle);
		}
	}

	public WorkerManager queue(RequestHandle handle)
	{
		WorkerTask task = new WorkerTask(handle, this);
		
		getPendingRequests().put(handle, task);
		
		executor.execute(new Thread(task));
		return this;
	}
	
	public WorkerManager cancelRequest(RequestHandle handle) throws Exception
	{
		WorkerTask task = getPendingRequests().get(handle);
		if(task != null)
		{
			try {
				task.cancel();
			}
			finally {
				getPendingRequests().remove(handle);
			}
		}
		
		return this;
	}
	
	public Map<RequestHandle, WorkerTask> getPendingRequests()
	{
		if(pendingRequests == null)
			pendingRequests = new HashMap<RequestHandle, WorkerTask>();
		return pendingRequests;
	}
}
